package com.hugang.juc.reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

/**
 * 虚引用示例
 * 结果：
 * java.lang.Object@677327b6
 * null
 * null
 *
 * null
 * null
 * java.lang.ref.PhantomReference@14ae5a5
 *
 * java提供了4种引用类型，在垃圾回收的时候，都有各自的特点。
 * ReferenceQueue是用来配合引用工作的，没有ReferenceQueue一样可以运行（虚引用不行）。
 *
 * 创建引用的时候可以指定管理的队列，当GC释放对象内存的时候，会将引用加入到引用队列，如果
 * 程序发现某个虚引用已经被加入到引用队列，那么就可以在所引用的对象的内存被回收之前采取必要
 * 的行动，这相当于一中通知机制。
 *
 * 当关联的引用队列中有数据的时候，意味着引用指向的堆内存中的对象被回收。通过这种方式，jvm允许我们在对象被销毁之后，
 * 做一些我们自己想做的事情。
 *
 * @author hg
 * @date 2020/8/26 16:25
 */
public class PhantomReferenceDemo {

    public static void main(String[] args) {
        Object o1 = new Object();
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        PhantomReference<Object> reference = new PhantomReference<>(o1,referenceQueue);

        System.out.println(o1);
        System.out.println(reference.get());
        System.out.println(referenceQueue.poll());
        System.out.println();

        o1 = null;
        System.gc();
        System.out.println(o1);
        System.out.println(reference.get());
        System.out.println(referenceQueue.poll());
    }
}
